99%的人都不知道的pandas骚操作(二)
-----这是 Python数据科学的第 49 篇原创文章-----
【作者】:xiaoyu
【介绍】:一个半路转行的数据挖掘工程师
【知乎专栏】:https://zhuanlan.zhihu.com/pypcfx
全文548字 | 阅读需要8分钟
【pandas骚操作系列】文章回顾:
上一篇介绍了accessor的用法,很多朋友看过后都恍然大悟,原来我们常用的str也只是其中之一而已。本篇我们将继续介绍几个pandas的骚操作。
从clipboard剪切板载入数据
将pandas对象转换为“压缩”格式
使用"测试模块"制作伪数据
从列项中创建DatetimeIndex
1从clipboard剪切板载入数据
当我们的数据存在excel表里,或者其它的IDE编辑器中的时候,我们想要通过pandas载入数据。我们通常的做法是先保存再载入,其实这样做起来十分繁琐。一个简单的方法就是使用 pd.read_clipboard() 直接从电脑的剪切板缓存区中提取数据。
这样我们就可以直接将结构数据转变为DataFrame或者Series了。excel表中数据是这样的:
在纯文本文件中,比如txt文件,是这样的:
a b c d
0 1 inf 1/1/00
2 7.389056099 N/A 5-Jan-13
4 54.59815003 nan 7/24/18
6 403.4287935 None NaT
将上面excel或者txt中的数据选中然后复制,然后使用pandas的read_clipboard()即可完成到DataFrame的转换。parse_dates参数设置为 "d",可以自动识别日期,并调整为xxxx-xx-xx的格式。
'd'])
> df
a b c d
0 0 1.0000 inf 2000-01-01
1 2 7.3891 NaN 2013-01-05
2 4 54.5982 NaN 2018-07-24
3 6 403.4288 NaN NaT
> df.dtypes
a int64
b float64
c float64
d datetime64[ns]
dtype: object
> df = pd.read_clipboard(na_values=[None], parse_dates=[2将pandas对象转换为“压缩”格式
在pandas中,我们可以直接将objects打包成为 gzip, bz2, zip, or xz 等压缩格式,而不必将没压缩的文件放在内存中然后进行转化。来看一个例子如何使用:
>>> abalone = pd.read_csv(url, usecols=[0, 1, 2, 3, 4, 8], names=cols)
>>> abalone
sex length diam height weight rings
0 M 0.455 0.365 0.095 0.5140 15
1 M 0.350 0.265 0.090 0.2255 7
2 F 0.530 0.420 0.135 0.6770 9
3 M 0.440 0.365 0.125 0.5160 10
4 I 0.330 0.255 0.080 0.2050 7
5 I 0.425 0.300 0.095 0.3515 8
6 F 0.530 0.415 0.150 0.7775 20
... .. ... ... ... ... ...
4170 M 0.550 0.430 0.130 0.8395 10
4171 M 0.560 0.430 0.155 0.8675 8
4172 F 0.565 0.450 0.165 0.8870 11
4173 M 0.590 0.440 0.135 0.9660 10
4174 M 0.600 0.475 0.205 1.1760 9
4175 F 0.625 0.485 0.150 1.0945 10
4176 M 0.710 0.555 0.195 1.9485 12
导入文件,读取并存为abalone(DataFrame结构)。当我们要存为压缩的时候,简单的使用 to_json() 即可轻松完成转化过程。下面通过设置相应参数将abalone存为了.gz格式的压缩文件。
abalone.to_json('df.json.gz', orient='records',
lines=True, compression='gzip')
如果我们想知道储存压缩文件的大小,可以通过内置模块os.path,使用getsize方法来查看文件的字节数。下面是两种格式储存文件的大小对比。
>>> import os.path
>>> abalone.to_json('df.json', orient='records', lines=True)
>>> os.path.getsize('df.json') / os.path.getsize('df.json.gz')
11.603035760226396
3使用"测试模块"制作伪数据
在pandas中,有一个测试模块可以帮助我们生成半真实(伪数据),并进行测试,它就是util.testing。下面同我们通过一个简单的例子看一下如何生成数据测试:
> tm.N, tm.K = 15, 3 # 默认的行和列
> import numpy as np
> np.random.seed(444)
> tm.makeTimeDataFrame(freq='M').head()
A B C
2000-01-31 0.3574 -0.8804 0.2669
2000-02-29 0.3775 0.1526 -0.4803
2000-03-31 1.3823 0.2503 0.3008
2000-04-30 1.1755 0.0785 -0.1791
2000-05-31 -0.9393 -0.9039 1.1837
> tm.makeDataFrame().head()
A B C
nTLGGTiRHF -0.6228 0.6459 0.1251
WPBRn9jtsR -0.3187 -0.8091 1.1501
7B3wWfvuDA -1.9872 -1.0795 0.2987
yJ0BTjehH1 0.8802 0.7403 -1.2154
0luaYUYvy1 -0.9320 1.2912 -0.2907
> import pandas.util.testing as tm上面简单的使用了makeTimeDataFrame 和 makeDataFrame 分别生成了一组时间数据和DataFrame的数据。但这只是其中的两个用法,关于testing中的方法有大概30多个,如果你想全部了解,可以通过查看dir获得:
>>> [i for i in dir(tm) if i.startswith('make')]
['makeBoolIndex',
'makeCategoricalIndex',
'makeCustomDataframe',
'makeCustomIndex',
# ...,
'makeTimeSeries',
'makeTimedeltaIndex',
'makeUIntIndex',
'makeUnicodeIndex']
4从列项中创建DatetimeIndex
也许我们有的时候会遇到这样的情形(为了说明这种情情况,我使用了product进行交叉迭代的创建了一组关于时间的数据):
> datecols = ['year', 'month', 'day']
> df = pd.DataFrame(list(product([2017, 2016], [1, 2], [1, 2, 3])),
... columns=datecols)
> df['data'] = np.random.randn(len(df))
> df
year month day data
0 2017 1 1 -0.0767
1 2017 1 2 -1.2798
2 2017 1 3 0.4032
3 2017 2 1 1.2377
4 2017 2 2 -0.2060
5 2017 2 3 0.6187
6 2016 1 1 2.3786
7 2016 1 2 -0.4730
8 2016 1 3 -2.1505
9 2016 2 1 -0.6340
10 2016 2 2 0.7964
11 2016 2 3 0.0005
> from itertools import product明显看到,列项中有year,month,day,它们分别在各个列中,而并非是一个完整日期。那么如何从这些列中将它们组合在一起并设置为新的index呢?
通过to_datetime的使用,我们就可以直接将年月日组合为一个完整的日期,然后赋给索引。代码如下:
> df.head()
year month day data
2017-01-01 2017 1 1 -0.0767
2017-01-02 2017 1 2 -1.2798
2017-01-03 2017 1 3 0.4032
2017-02-01 2017 2 1 1.2377
2017-02-02 2017 2 2 -0.2060
> df.index = pd.to_datetime(df[datecols])当然,你可以选择将原有的年月日列移除,只保留data数据列,然后squeeze转换为Series结构。
1).squeeze()
> df.head()
2017-01-01 -0.0767
2017-01-02 -1.2798
2017-01-03 0.4032
2017-02-01 1.2377
2017-02-02 -0.2060
Name: data, dtype: float64
> df.index.dtype_str
'datetime64[ns]
> df = df.drop(datecols, axis=https://realpython.com/
以上就是本次的4个骚操作,
如果你还知道什么好的骚操作,欢迎在下方留言分享。
推荐阅读: